# 导入必要的库
import asyncio  # 用于支持异步IO操作
import websockets  # WebSocket协议的实现库
import json  # 用于JSON数据的编码和解码

# 创建一个集合(set)用来存储所有连接的WebSocket客户端
# 使用set是因为它能确保每个客户端只存储一次，且支持快速的添加和删除操作
connected_clients = set()

async def handle_message(websocket):
    """
    处理单个WebSocket连接的主要函数
    参数 websocket: WebSocket连接对象，代表与客户端的连接
    """
    # 向新连接的客户端发送欢迎消息
    await websocket.send(json.dumps({
                    'sender': '系统消息',  # 发送者显示为"系统消息"
                    'message': '欢迎来到聊天室'  # 欢迎信息内容
                }, ensure_ascii=False))  # ensure_ascii=False允许中文字符正常显示
    
    # 将新连接的客户端添加到集合中，以便后续广播消息
    connected_clients.add(websocket)
    
    try:
        # 持续监听来自这个客户端的消息
        async for message in websocket:
            # 将接收到的JSON字符串解析为Python字典
            data = json.loads(message)
            
            # 将消息广播给所有连接的客户端（包括发送者）
            for client in connected_clients:
                # 将消息转换为JSON字符串并发送
                await client.send(json.dumps({
                    'sender': data.get('sender', 'Anonymous'),  # 如果没有sender字段，默认为'Anonymous'
                    'message': data.get('message', '')  # 如果没有message字段，默认为空字符串
                }, ensure_ascii=False))  # 确保中文能正确显示
                
    except websockets.exceptions.ConnectionClosed:
        # 如果连接异常关闭，静默处理异常
        pass
    finally:
        # 无论是正常关闭还是异常关闭，都要确保将客户端从集合中移除
        connected_clients.remove(websocket)

async def main():
    """
    服务器的主入口函数，负责启动WebSocket服务器
    """
    # 启动WebSocket服务器
    # localhost: 服务器地址，只允许本机连接
    # 8765: 服务器端口号
    async with websockets.serve(handle_message, "localhost", 8765):
        print("WebSocket server started on ws://localhost:8765")  # 打印服务器启动信息
        await asyncio.Future()  # 保持服务器运行，直到被手动终止

# 程序入口点
if __name__ == "__main__":
    # 启动异步事件循环，运行main()函数
    asyncio.run(main())